/*
 * Copyright (c) 2008, 2024 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Linda DeMichiel - 2.1
//     Linda DeMichiel - 2.0


package jakarta.persistence;

import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Specifies the column mapped by the annotated persistent property
 * or field.
 *
 * <p>If no {@code Column} annotation is explicitly specified, the
 * default values apply.
 *
 * <p>Example 1:
 * {@snippet :
 * @Column(name = "DESC", nullable = false, length = 512)
 * public String getDescription() { return description; }
 * }
 *
 * <p>Example 2:
 * {@snippet :
 * @Column(name = "DESC",
 *         columnDefinition = "CLOB NOT NULL",
 *         table = "EMP_DETAIL")
 * @Lob
 * public String getDescription() { return description; }
 * }
 *
 * <p>Example 3:
 * {@snippet :
 * @Column(name = "ORDER_COST", updatable = false, precision = 12, scale = 2)
 * public BigDecimal getCost() { return cost; }
 * }
 *
 * <p>
 * Portable applications which make use of schema generation should
 * explicitly specify the {@link #precision} and {@link #scale} of
 * columns of type {@code numeric} or {@code decimal}.
 *
 * @since 1.0
 */ 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface Column {

    /**
     * (Optional) The name of the column. Defaults to the property
     * or field name.
     */
    String name() default "";

    /**
     * (Optional) Whether the column is a unique key. This is a
     * shortcut for the {@link UniqueConstraint} annotation at
     * the table level and is useful for when the unique key
     * constraint corresponds to only a single column. This
     * constraint applies in addition to any constraint entailed
     * by the primary key mapping and to constraints specified at
     * the table level.
     */
    boolean unique() default false;

    /**
     * (Optional) Whether the database column is nullable.
     */
    boolean nullable() default true;

    /**
     * (Optional) Whether the column is included in SQL INSERT 
     * statements generated by the persistence provider.
     */
    boolean insertable() default true;

    /**
     * (Optional) Whether the column is included in SQL UPDATE 
     * statements generated by the persistence provider.
     */
    boolean updatable() default true;

    /**
     * (Optional) The SQL fragment that is used when generating
     * the DDL for the column.
     * <p> Defaults to the generated SQL to create a column of
     * the inferred type.
     * <p>
     * The specified DDL must be written in the native SQL dialect
     * of the target database, and is not portable across databases.
     */
    String columnDefinition() default "";

    /**
     * (Optional) A SQL fragment appended to the generated DDL
     * which declares this column. May not be used in conjunction
     * with {@link #columnDefinition()}.
     * <p>
     * The specified DDL must be written in the native SQL dialect
     * of the target database, and is not portable across databases.
     *
     * @since 3.2
     */
    String options() default "";

    /**
     * (Optional) The name of the table that contains the column. 
     * If absent the column is assumed to be in the primary table.
     */
    String table() default "";

    /**
     * (Optional) The column length.
     * <p>
     * Applies only to columns whose type is parameterized by length,
     * for example, {@code varchar} or {@code varbinary} types.
     */
    int length() default 255;

    /**
     * (Optional) The precision for a column of SQL type {@code decimal}
     * or {@code numeric}, or of similar database-native type.
     * <p>
     * Applies only to columns of exact numeric type.
     * <p>
     * The default value {@code 0} indicates that a provider-determined
     * precision should be inferred.
     */
    int precision() default 0;

    /**
     * (Optional) The scale for a column of SQL type {@code decimal} or
     * {@code numeric}, or of similar database-native type.
     * <p>
     * Applies only to columns of exact numeric type.
     * <p>
     * The default value {@code 0} indicates that a provider-determined
     * scale should be inferred.
     */
    int scale() default 0;

    /**
     * (Optional) The number of decimal digits to use for storing
     * fractional seconds in a SQL {@code time} or {@code timestamp}
     * column.
     * <p>
     * Applies only to columns of time or timestamp type.
     * <p>
     * The default value {@code -1} indicates that fractional seconds
     * should not be stored in a {@code time} column, or that the
     * maximum number of digits supported by the database and JDBC
     * driver should be stored in a {@code timestamp} column.
     *
     * @since 3.2
     */
    int secondPrecision() default -1;

    /**
     * (Optional) Check constraints to be applied to the column.
     * These are only used if table generation is in effect.
     *
     * @since 3.2
     */
    CheckConstraint[] check() default {};

    /**
     * (Optional) A comment to be applied to the column.
     * This is only used if table generation is in effect.
     *
     * @since 3.2
     */
    String comment() default "";
}
